﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GraphicsFramework;

namespace GraphicsFramework
{
    public class DrawingLibrary
    {

        #region Variables

        //Graphics
        private GraphicsFramework graphics;

        //Drawing Collections
        private Collection.Grid grids = new Collection.Grid();
        private Collection.General drawings = new Collection.General();

        private Drawing.GraphicBase guide;
        private Drawing.Miscellaneous.Guide selectionguide;

        private bool showgrid = true;
        private bool snap = true;

        //Copy and Paste
        private Support.CopyPaste copy;

        //Supports
        private Support.ShortCutCollection shortcuts = new Support.ShortCutCollection();
        private Support.MouseCollection mouse = new Support.MouseCollection();
        private Support.Keyboard keyboard = new Support.Keyboard();

        //Command
        private Enum.EnumDrawingCommands command = Enum.EnumDrawingCommands.SELECT;

        #endregion

        #region Events

        public delegate void RefreshDrawingDelegate();
        public event RefreshDrawingDelegate RefreshDrawing;

        public delegate void CommandUpdatedDelegate(Enum.EnumDrawingCommands type, string command);
        public event CommandUpdatedDelegate CommandUpdated;

        public delegate void DrawingSelectedDelegate(Drawing.Base[] selected);
        public event DrawingSelectedDelegate DrawingSelected;

        public delegate void DrawingDeselectedDelegate();
        public event DrawingDeselectedDelegate DrawingDeselected;

        #endregion

        #region Constructors

        public DrawingLibrary(GraphicsFramework graphics)
        {
            this.graphics = graphics;
            this.copy = new Support.CopyPaste();
            this.copy.Location = new Entity.Point2F(0.5F, 0.5F);

            mouse.DrawingComplete += new Support.MouseCollection.DrawingCompleteDelegate(DrawingComplete);
        }

        #endregion

        #region Events Handling

        /// <summary>
        /// Activate the OnRender event.
        /// </summary>
        public void OnRender()
        {
            if (showgrid)
                grids.OnRender(graphics);

            drawings.OnRender(graphics);

            drawings.OnRenderNode(graphics);

            if (guide != null)
                guide.OnRender(graphics);

            if (selectionguide != null)
                selectionguide.OnRender(graphics);
        }

        /// <summary>
        /// Activate the OnResize event.
        /// </summary>
        public void OnResize(int width, int height)
        {
            graphics.Resize(width, height);
            RefreshDrawing();
        }

        /// <summary>
        /// Activate the OnKeyDown event.
        /// </summary>
        public void OnKeyDown(Enum.EnumKeys key, bool control, bool shift, bool alt)
        {

            keyboard = new Support.Keyboard(key, control, shift, alt, Enum.EnumActionShortcuts.NONE);

            foreach (Support.Keyboard shortcut in shortcuts)
            {
                if ((shortcut.Key == key) && (shortcut.Control == control) && (shortcut.Shift == shift) && (shortcut.Alt == alt))
                {
                    switch (shortcut.Action)
                    {
                        case Enum.EnumActionShortcuts.ADDNODE:
                            if (drawings.SelectedCount != 0)
                            {
                                command = Enum.EnumDrawingCommands.ADDNODE;
                                CommandUpdated(command, "Add Node");
                            }
                            return;

                        //Copy and Paste
                        case Enum.EnumActionShortcuts.COPY:
                            Copy();
                            return;

                        case Enum.EnumActionShortcuts.CUT:
                            Cut();
                            return;

                        case Enum.EnumActionShortcuts.PASTE:
                            Paste();
                            return;

                        //Drawing
                        case Enum.EnumActionShortcuts.SELECTALLDRAWING:
                            SelectAllDrawing();
                            return;

                        case Enum.EnumActionShortcuts.ENDDRAWING:
                            if (command == Enum.EnumDrawingCommands.DRAW) DrawingComplete();
                            return;

                        case Enum.EnumActionShortcuts.CANCELDRAWING:
                            CancelDrawing();
                            return;

                        case Enum.EnumActionShortcuts.DELETE:
                            drawings.Delete();
                            RefreshDrawing();
                            return;

                        case Enum.EnumActionShortcuts.DRAWLINE:
                            StartDrawing(new Drawing.Primitive.Line());
                            return;

                        case Enum.EnumActionShortcuts.DRAWPOLYLINE:
                            StartDrawing(new Drawing.Primitive.Polyline());
                            return;

                        case Enum.EnumActionShortcuts.DRAWPOLYGON:
                            StartDrawing(new Drawing.Primitive.Polygon());
                            return;

                        case Enum.EnumActionShortcuts.DRAWRECTANGLE:
                            StartDrawing(new Drawing.Primitive.Rectangle());
                            return;

                        case Enum.EnumActionShortcuts.DRAWCIRCLE:
                            StartDrawing(new Drawing.Primitive.Circle());
                            return;

                        case Enum.EnumActionShortcuts.DRAWSTRING:
                            StartDrawing(new Drawing.Primitive.TextBlock());
                            return;

                        //Panning
                        case Enum.EnumActionShortcuts.MOVELEFT:
                            MoveLeft();
                            return;

                        case Enum.EnumActionShortcuts.MOVERIGHT:
                            MoveRight();
                            return;

                        case Enum.EnumActionShortcuts.MOVEUP:
                            MoveUp();
                            return;

                        case Enum.EnumActionShortcuts.MOVEDOWN:
                            MoveDown();
                            return;

                        case Enum.EnumActionShortcuts.ROTATELEFT:
                            Rotate(1);
                            return;

                        case Enum.EnumActionShortcuts.ROTATERIGHT:
                            Rotate(-1);
                            return;

                        //Zoom
                        case Enum.EnumActionShortcuts.ZOOMIN:
                            ZoomIn();
                            return;

                        case Enum.EnumActionShortcuts.ZOOMOUT:
                            ZoomOut();
                            return;

                        case Enum.EnumActionShortcuts.ZOOMEXTENT:
                            ZoomExtent();
                            return;

                        case Enum.EnumActionShortcuts.ZOOMWINDOW:
                            ZoomWindow();
                            return;

                        //GRID
                        case Enum.EnumActionShortcuts.SHOWGRID:
                            ShowGrid = !ShowGrid;
                            return;

                    }
                }
            }

        }

        public void OnKeyUp(Enum.EnumKeys key, bool control, bool shift, bool alt)
        {
            keyboard = new Support.Keyboard(Enum.EnumKeys.None, false, false, false, Enum.EnumActionShortcuts.NONE);
        }

        /// <summary>
        /// Activate the OnMouseDown event.
        /// </summary>
        public void OnMouseDown(int x, int y, Enum.EnumMouseButtons button)
        {
            //Store mouse
            mouse.Down = new Support.Mouse(graphics, new Entity.Point2I(x, y));
            mouse.Previous = new Support.Mouse(graphics, new Entity.Point2I(x, y));

            //Clear previous selection guide
            selectionguide = null;

            //Process mouse
            switch (button)
            {
                //Left button
                case Enum.EnumMouseButtons.LEFT:

                    //Drawing mode
                    if ((command == Enum.EnumDrawingCommands.DRAW) || (command == Enum.EnumDrawingCommands.ZOOMWINDOW))
                    {
                        if (keyboard.Key != Enum.EnumKeys.Space)
                        {
                            mouse.Add(mouse.Down.WorkingCoordinate.Clone());
                        }
                    }
                    //Select mode
                    else if ((command == Enum.EnumDrawingCommands.SELECT) && !((keyboard.Key == Enum.EnumKeys.Space) || (command == Enum.EnumDrawingCommands.PAN)))
                    {
                        if ((drawings.SelectedCount > 1) && (!keyboard.Control))
                        {
                            if (!TestSelectByPoint(mouse.Down.ActualCoordinate))
                                SelectByPoint(mouse.Down.ActualCoordinate, keyboard.Control);
                        }
                        else if (keyboard.Control)
                        {
                            if (!TestSelectByPoint(mouse.Down.ActualCoordinate))
                            {
                                drawings.ClearSelection();
                                RefreshDrawing();
                            }
                            else
                            {
                                SelectByPoint(mouse.Down.ActualCoordinate, keyboard.Control);
                            }
                        }
                        else
                        {
                            if (!drawings.RetestSelectedByPoint(graphics, mouse.Down.ActualCoordinate))
                                SelectByPoint(mouse.Down.ActualCoordinate, keyboard.Control);
                            else
                                SelectByPoint(mouse.Down.ActualCoordinate, keyboard.Control, false);
                        }
                    }
                    //Add node mode
                    else if (command == Enum.EnumDrawingCommands.ADDNODE)
                    {
                        AddNode();
                    }
                    break;

                case Enum.EnumMouseButtons.MIDDLE:
                    break;

                case Enum.EnumMouseButtons.RIGHT:
                    if (command == Enum.EnumDrawingCommands.DRAW)
                    {
                        DrawingComplete();
                    }
                    else if (command == Enum.EnumDrawingCommands.ADDNODE)
                    {
                        CancelDrawing();
                    }
                    break;
            }

        }

        /// <summary>
        /// Activate the OnMouseMove event.
        /// </summary>
        public void OnMouseMove(int x, int y, Enum.EnumMouseButtons button)
        {
            mouse.Current = new Support.Mouse(graphics, new Entity.Point2I(x, y));

            switch (button)
            {
                case Enum.EnumMouseButtons.LEFT:
                    if ((keyboard.Key == Enum.EnumKeys.Space) || (command == Enum.EnumDrawingCommands.PAN))
                    {
                        //Pan - move the grid.
                        graphics.Move(mouse.Current.ActualCoordinate, mouse.Previous.ActualCoordinate);
                    }
                    else if (command == Enum.EnumDrawingCommands.ZOOMWINDOW)
                    {
                        if (mouse.Down != null)
                            selectionguide = new Drawing.Miscellaneous.Guide(mouse.Down.RawCoordinate, mouse.Current.RawCoordinate);
                    }
                    else
                    {
                        //Check if there is a current selection.
                        if (drawings.SelectedCount != 0)
                        {
                            //Move selected drawings.
                            MoveSelectedDrawings();
                        }
                        else if (mouse.Down != null)
                        {
                            selectionguide = new Drawing.Miscellaneous.Guide(mouse.Down.RawCoordinate, mouse.Current.RawCoordinate);
                        }
                    }

                    RefreshDrawing();
                    break;

                case Enum.EnumMouseButtons.MIDDLE:
                    //Pan - move the grid.
                    graphics.Move(mouse.Current.ActualCoordinate, mouse.Previous.ActualCoordinate);
                    RefreshDrawing();
                    break;

                case Enum.EnumMouseButtons.RIGHT:
                    break;

                default:
                    if (command != Enum.EnumDrawingCommands.SELECT)
                    {
                        if ((mouse.Clicks.Count != 0) && (guide != null))
                        {
                            //Update the drawing guide.
                            guide.UpdateGuide(mouse.Clicks, mouse.Current.WorkingCoordinate.Clone());
                            RefreshDrawing();
                        }
                    }

                    break;
            }

            mouse.Previous = new Support.Mouse(graphics, new Entity.Point2I(x, y));
        }

        /// <summary>
        /// Activate the OnMouseUp event.
        /// </summary>
        public void OnMouseUp(int x, int y, Enum.EnumMouseButtons button)
        {
            mouse.Current = new Support.Mouse(graphics, new Entity.Point2I(x, y));

            if ((button == Enum.EnumMouseButtons.LEFT) || (button == Enum.EnumMouseButtons.NONE))
            {
                //Selection guide is active
                if (selectionguide != null)
                {
                    //Check if on ZoomWindow.
                    if (command == Enum.EnumDrawingCommands.ZOOMWINDOW)
                    {
                        mouse.Add(mouse.Current.WorkingCoordinate);
                    }
                    else
                    {
                        //Select by rectangle.
                        selectionguide = null;
                        SelectByRectangle(new Entity.Rectangle2F(mouse.Down.ActualCoordinate, mouse.Current.ActualCoordinate));
                    }
                }
            }
        }

        /// <summary>
        /// Activate the OnMouseWheel event.
        /// </summary>
        public void OnMouseWheel(int x, int y, int delta)
        {
            graphics.Zoom(x, y, delta);
            RefreshDrawing();
        }

        #endregion

        #region Supporting Functions

        public void SelectAllDrawing()
        {
            drawings.SelectAllDrawing();
            RefreshDrawing();
        }

        /// <summary>
        /// Select drawing by point selection.
        /// </summary>
        public void SelectByPoint(Entity.Point2F point, bool multiselect, bool clearjustpasted = true)
        {
            int prev = drawings.SelectedCount;

            drawings.SelectByPoint(graphics, point, multiselect);

            if (drawings.SelectedCount != 0)
            {
                if (DrawingSelected != null)
                {
                    DrawingSelected(GetSelectedDrawings());
                }
                else
                {
                    if (prev != drawings.SelectedCount)
                        DrawingDeselected();
                }
            }
            else
            {
                if (prev != drawings.SelectedCount)
                    DrawingDeselected();
            }

            if (clearjustpasted)
                copy.OnArray = false;

            RefreshDrawing();
        }

        public bool TestSelectByPoint(Entity.Point2F point)
        {
            return drawings.TestSelectByPoint(graphics, point);
        }

        /// <summary>
        /// Select drawing by rectangle selection.
        /// </summary>
        public void SelectByRectangle(Entity.Rectangle2F bounds)
        {
            int prev = drawings.SelectedCount;

            drawings.SelectByRectangle(graphics, bounds);

            if (drawings.SelectedCount != 0)
            {
                if (DrawingSelected != null)
                {
                    DrawingSelected(GetSelectedDrawings());
                }
                else if (prev != drawings.SelectedCount)
                {
                    DrawingDeselected();
                }
            }
            else
            {
                if (prev != drawings.SelectedCount)
                    DrawingDeselected();
            }

            copy.OnArray = false;
            RefreshDrawing();
        }

        /// <summary>
        /// Select drawing by point selection.
        /// </summary>
        public void SelectByPoint(float x, float y, bool multiselect)
        {
            SelectByPoint(new Entity.Point2F(x, y), multiselect);
        }

        public void FlipHorizontal()
        {
            drawings.FlipHorizontal();
            RefreshDrawing();
        }

        public void FlipVertical()
        {
            drawings.FlipVertical();
            RefreshDrawing();
        }

        public void Rotate(float angle)
        {
            if (copy.OnArray)
                copy.Rotation += angle;

            drawings.Rotate(angle, graphics.Precision);
            RefreshDrawing();
        }

        public void RotateLeft()
        {
            drawings.RotateLeft(graphics.Precision);
            RefreshDrawing();
        }

        public void RotateRight()
        {
            drawings.RotateRight(graphics.Precision);
            RefreshDrawing();
        }

        public void ZoomIn()
        {
            graphics.ZoomIn();
            RefreshDrawing();
        }

        public void ZoomOut()
        {
            graphics.ZoomOut();
            RefreshDrawing();
        }

        public void ZoomExtent()
        {
            if (drawings.Count != 0)
            {
                //Get drawing boundary
                Entity.Rectangle2F bounds = GetBounds();

                //Check if boundary is null
                if (bounds != null)
                {
                    float width = (float)(bounds.Width * 0.025);
                    float height = (float)(bounds.Height * 0.025);

                    graphics.Zoom(bounds.Point1.X - width, bounds.Point1.Y - height, bounds.Point2.X + width, bounds.Point2.Y + height);
                    RefreshDrawing();
                }
            }
        }

        public void ZoomWindow()
        {
            command = Enum.EnumDrawingCommands.ZOOMWINDOW;
            mouse.Start(Enum.EnumMouseClicks.TWO);
        }

        public void Pan()
        {
            command = Enum.EnumDrawingCommands.PAN;
        }

        public void AddNode()
        {
            drawings.AddNode(graphics, mouse.Down.ActualCoordinate);
            RefreshDrawing();
        }

        public void LeftAlign()
        {
            drawings.LeftAlign();
            RefreshDrawing();
        }

        public void RightAlign()
        {
            drawings.RightAlign();
            RefreshDrawing();
        }

        public void TopAlign()
        {
            drawings.TopAlign();
            RefreshDrawing();
        }

        public void BottomAlign()
        {
            drawings.BottomAlign();
            RefreshDrawing();
        }

        public void HorizontalCenterAlign()
        {
            drawings.HorizontalCenterAlign();
            RefreshDrawing();
        }

        public void VerticalCenterAlign()
        {
            drawings.VerticalCenterAlign();
            RefreshDrawing();
        }

        private void MoveSelectedDrawings()
        {
            Entity.Point2F value = new Entity.Point2F(mouse.Current.WorkingCoordinate.X - mouse.Previous.WorkingCoordinate.X,
                                                     mouse.Current.WorkingCoordinate.Y - mouse.Previous.WorkingCoordinate.Y);

            MoveSelectedDrawings(value);
        }

        private void MoveSelectedDrawings(Entity.Point2F value)
        {
            if ((value.X != 0) || (value.Y != 0))
                drawings.Move(value, graphics.SnapValue);

            if (copy.OnArray)
            {
                foreach (Drawing.GraphicBase drawing in copy.Board)
                {
                    drawing.Move(value, graphics.SnapValue);
                }
                copy.Location.Move(value);
            }
        }

        private void MoveLeft()
        {
            if (drawings.SelectedCount != 0)
            {
                MoveSelectedDrawings(new Entity.Point2F(-graphics.SnapValue.X, 0));
            }
            else
            {
                graphics.MoveLeft();
            }

            RefreshDrawing();
        }

        private void MoveRight()
        {
            if (drawings.SelectedCount != 0)
            {
                MoveSelectedDrawings(new Entity.Point2F(graphics.SnapValue.X, 0));
            }
            else
            {
                graphics.MoveRight();
            }

            RefreshDrawing();
        }

        private void MoveUp()
        {
            if (drawings.SelectedCount != 0)
            {
                MoveSelectedDrawings(new Entity.Point2F(0, graphics.SnapValue.Y));
            }
            else
            {
                graphics.MoveUp();
            }

            RefreshDrawing();
        }

        private void MoveDown()
        {
            if (drawings.SelectedCount != 0)
            {
                MoveSelectedDrawings(new Entity.Point2F(0, -graphics.SnapValue.Y));
            }
            else
            {
                graphics.MoveDown();
            }

            RefreshDrawing();
        }

        #endregion

        #region Drawings

        /// <summary>
        /// Start drawing using the drawing parameter.
        /// </summary>
        public void StartDrawing(Drawing.GraphicBase drawing)
        {
            mouse.Start(drawing.MouseClick);
            command = Enum.EnumDrawingCommands.DRAW;

            guide = drawing;
            guide.IsConstructionLine = true;
            drawings.ClearSelection();

            copy.OnArray = false;
            CommandUpdated(command, drawing.Description);
        }

        public void SelectDrawing()
        {
            CancelDrawing();
        }

        private void CancelDrawing()
        {
            command = Enum.EnumDrawingCommands.SELECT;
            mouse.Clicks.Clear();

            selectionguide = null;
            guide = null;

            copy.OnArray = false;
            RefreshDrawing();
            CommandUpdated(command, "Ready");
        }

        private void DrawingComplete()
        {
            if (IsDrawingValid())
            {

                //If drawing requires only one (1) click.
                if (guide.MouseClick == Enum.EnumMouseClicks.ONE)
                    guide.UpdateGuide(mouse.Clicks, mouse.Current.WorkingCoordinate.Clone());

                //Check if drawing guide is null.
                if (guide == null)
                {
                    //Drawing is not valid. Cancel the drawing.
                    CancelDrawing();
                    return;
                }

                guide.IsConstructionLine = false;

                //Add the guide to the drawing list.
                drawings.Add(guide.Clone());

                //Start a new drawing.
                StartDrawing(guide.Clone());

                //Refresh drawing after drawing is complete.
                RefreshDrawing();
            }
        }

        /// <summary>
        /// Check if current drawing command is valid.
        /// </summary>
        /// <returns>Returns true if valid. False if otherwise.</returns>
        private bool IsDrawingValid()
        {
            //Check if command is ZoomWindow.
            //ZoomWindow is considered a command because we need to draw rectangle to show the boundary of the zoom.
            if (command == Enum.EnumDrawingCommands.ZOOMWINDOW)
            {
                //Call zoom function using mouse down and mouse current coordinate as parameter.
                graphics.Zoom(mouse.Down.ActualCoordinate.X, mouse.Down.ActualCoordinate.Y,
                              mouse.Current.ActualCoordinate.X, mouse.Current.ActualCoordinate.Y);

                //Call CancelDrawing after ZoomWindow to reset drawing command.
                CancelDrawing();
                return false;

            }
            else if (guide != null)
            {
                //Check if drawing is of type polyline.
                if (guide.MouseClick == Enum.EnumMouseClicks.POLYLINE)
                {
                    //There should be at least 2 points (LINE) to create a polyline.
                    if (mouse.Clicks.Count <= 1)
                    {
                        //Drawing is not valid. Cancel the drawing.
                        CancelDrawing();
                        return false;
                    }

                    //Remove and get the last point in the click and use it to update the drawing guide.
                    //This is to avoid duplicating the points.
                    //The mouse.current coordinate will be removed from the guide since this is not a click.
                    //Please check the OnMouseMove under the switch default.
                    Entity.Point2F point = mouse.RemoveAndGetLast();
                    guide.UpdateGuide(mouse.Clicks, point.Clone());

                }
                //Check if drawing is of type polygon.
                else if (guide.MouseClick == Enum.EnumMouseClicks.POLYGON)
                {
                    //There should be at least 3 points (TRIANGLE) to create a polygon.
                    if (mouse.Clicks.Count <= 2)
                    {
                        //Drawing is not valid. Cancel the drawing.
                        CancelDrawing();
                        return false;
                    }

                    //Remove and get the last point in the click and use it to update the drawing guide.
                    //This is to avoid duplicating the points.
                    //The mouse.current coordinate will be removed from the guide since this is not a click.
                    //Please check the OnMouseMove under the switch default.
                    Entity.Point2F point = mouse.RemoveAndGetLast();
                    guide.UpdateGuide(mouse.Clicks, point.Clone());
                }
                //Check if mouse click is less than the required mouse click
                else if (mouse.Clicks.Count < (int)guide.MouseClick)
                {
                    //Drawing is not valid. Cancel the drawing.
                    CancelDrawing();
                    return false;
                }
            }

            return true;
        }

        public void StartDrawingLine()
        {
            StartDrawing(new Drawing.Primitive.Line());
        }

        public void StartDrawingPolyline()
        {
            StartDrawing(new Drawing.Primitive.Polyline());
        }

        public void StartDrawingRectangle()
        {
            StartDrawing(new Drawing.Primitive.Rectangle());
        }

        public void StartDrawingPolygon()
        {
            StartDrawing(new Drawing.Primitive.Polygon());
        }

        public void AddDrawing(Drawing.GraphicBase drawing)
        {
            drawings.Add(drawing);
        }

        public void AddGrid(Drawing.Grid.BaseGrid drawing)
        {
            grids.Add((Drawing.Grid.BaseGrid)drawing);
        }

        public void Cut()
        {
            //Copy the selected drawing.
            Copy();

            //Delete the selected drawings.
            drawings.Delete();

            //Refresh the viewer.
            RefreshDrawing();
        }

        public void Copy()
        {
            //Copy the selected drawing.
            copy.Copy(drawings.SelectedDrawings);
        }

        public void Paste()
        {
            Drawing.GraphicBase paste;

            //Clear selection
            drawings.ClearSelection();

            //Paste all contents of the copy board.
            foreach (Drawing.GraphicBase drawing in copy.Board)
            {
                //Move by a point so that it will not be on the same location as the original one.
                drawing.Move(copy.Location, graphics.SnapValue);

                //Rotate the drawing
                if (copy.Rotation != 0)
                {
                    //Update the center after moving.
                    copy.UpdateCenter();

                    //Rotate the drawing base on the updated center
                    drawing.Rotate(copy.Center, copy.Rotation, graphics.Precision);
                }

                //Add the drawing to the list. It is very important to add the clone, 
                //not the exact one in the copy board.
                paste = drawing.Clone();

                //Set as selected so that we can move drawing after pasting.
                //This is very useful when there are more than one drawing in the copy board.
                paste.Selected = true;
                drawings.Add(paste);
            }

            //This will update the selected drawings.
            drawings.UpdateSelection();

            //For array
            copy.OnArray = true;

            //Refresh the canvas.
            RefreshDrawing();
        }

        #endregion

        #region Properties

        public Entity.Point2I RawCoordinate
        {
            get { return mouse.Current.RawCoordinate; }
        }

        public Entity.Point2F WorkingCoordinate
        {
            get { return mouse.Current.WorkingCoordinate; }
        }

        public Entity.Point2F ActualCoordinate
        {
            get { return mouse.Current.ActualCoordinate; }
        }

        public Entity.Rectangle2F GetBounds()
        {
            return drawings.Bounds();
        }

        public bool ShowGrid
        {
            get { return showgrid; }
            set { showgrid = value; RefreshDrawing(); }
        }

        public bool Snap
        {
            get { return snap; }
            set { snap = value; mouse.Snap = value; }
        }

        public Drawing.GraphicBase[] GetSelectedDrawings()
        {
            return drawings.SelectedDrawings.ToArray();
        }

        #endregion

    }
}
